﻿using System;

namespace SocialKit.LightRest
{
    /// <summary>
    /// Represents the request message of a RestClient.
    /// </summary>
    public class HttpRequestMessage : IDisposable
    {
        /// <summary>
        /// Gets or sets a string value indicates the http method.
        /// </summary>
        public string Method { get; set; }

        /// <summary>
        /// Gets the Uniform Resource Identifier (URI) of the Internet resource that actually responds to the request.
        /// </summary>
        public Uri Uri { get; set; }

        /// <summary>
        /// Gets the length of the content of request http body.
        /// </summary>
        public long? ContentLength { get; private set; }

        /// <summary>
        /// Gets a string value indicates the content type.
        /// </summary>
        public string ContentType { get; private set; }

        /// <summary>
        /// Gets a byte array indicates the request http body.
        /// </summary>
        public byte[] Content { get; private set; }

        /// <summary>
        /// Create an instance of SocialKit.LightRest.HttpRequestMessage class.
        /// </summary>
        /// <param name="method">The method used to send this request.</param>
        /// <param name="uri">The URI to be requested.</param>
        /// <param name="creator">A request http body creator.</param>
        public HttpRequestMessage(string method, Uri uri, IHttpContentCreator creator)
        {
            this.Method = method;
            this.Uri = uri;

            this.Content = creator.CreateContent();
            this.ContentLength = this.Content.Length;
            this.ContentType = creator.ContentType;
        }

        /// <summary>
        /// Create an instance of SocialKit.LightRest.HttpRequestMessage class.
        /// </summary>
        /// <param name="method">The method used to send this request.</param>
        /// <param name="uri">The URI to be requested.</param>
        public HttpRequestMessage(string method, Uri uri)
        {
            this.Method = method;
            this.Uri = uri;
        }

        /// <summary>
        /// Create an instance of SocialKit.LightRest.HttpRequestMessage class.
        /// </summary>
        public HttpRequestMessage()
        {
            this.Method = HttpMethod.GET.ToString();
        }

        /// <summary>
        /// Create an instance of SocialKit.LightRest.HttpRequestMessage class.
        /// </summary>
        /// <param name="method">The method used to send this request.</param>
        /// <param name="uri">The URI string to be requested.</param>
        /// <param name="creator">A request http body creator.</param>
        public HttpRequestMessage(string method, string uri, IHttpContentCreator creator)
            : this(method, new Uri(uri, UriKind.RelativeOrAbsolute), creator)
        {
        }

        /// <summary>
        /// Create an instance of SocialKit.LightRest.HttpRequestMessage class.
        /// </summary>
        /// <param name="method">The method used to send this request.</param>
        /// <param name="uri">The URI string to be requested.</param>
        public HttpRequestMessage(string method, string uri)
            : this(method, new Uri(uri, UriKind.RelativeOrAbsolute))
        {
        }

        /// <summary>
        /// Sets the request http body content and returns this HttpRequestMessage.
        /// </summary>
        /// <param name="creator">A request http body creator.</param>
        /// <returns></returns>
        public virtual HttpRequestMessage SetContent(IHttpContentCreator creator)
        {
            this.Content = creator.CreateContent();
            this.ContentLength = this.Content.Length;
            this.ContentType = creator.ContentType;

            return this;
        }

        #region IDisposable Members

        /// <summary>
        /// Dispose the content of this request message.
        /// </summary>
        public void Dispose()
        {
            if (this.Content != null)
            {
                this.Content = null;
            }
        }

        #endregion
    }
}